package order

import (
	"context"
	"strconv"
	"strings"

	"mall/common/globalkey"
	"mall/common/jwt"
	"mall/common/resultx"
	"mall/common/utils/pointy"
	"mall/service/forum/api/internal/logic/util"
	"mall/service/forum/api/internal/svc"
	"mall/service/forum/api/internal/types"
	"mall/service/forum/api/internal/utils/parse"
	"mall/service/order/rpc/orderclient"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetOrderListLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewGetOrderListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetOrderListLogic {
	return &GetOrderListLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *GetOrderListLogic) GetOrderList(
	req *types.GetOrderListReq,
	headers *[]*types.Header,
) (*types.OrderListResp, error) {
	userId := jwt.GetUserId(l.ctx)
	if userId == 0 {
		return nil, resultx.NewErrCode(resultx.TOKEN_EXPIRE_ERROR)
	}

	page, pageSize := parse.ParsePageInfo(
		req.Current,
		req.PageSize,
		l.svcCtx.Config.Query.DefaultAmount,
		l.svcCtx.Config.Query.MaxAmount,
	)

	preload := "order:Id,Sn,TradeState,Quantity,RetailAmount,Freight,DiscountAmount,AdjustAmount,ActualAmount,Amount,RefundAmount"
	preload += ",Remark,CreatedAt,UpdatedAt,PaidAt,ShippedAt,DeliveredAt,ConfirmedAt,ReviewedAt,ClosedAt,Growth,Integrals"
	preload += ";orderItem:Id,SkuId,Sku,ImageId,ImageUrl,ProductId,EntryId,Title,Slug,ProductType,BrandId,BrandTitle,BrandSlug,RetailPrice"
	preload += ",Quantity,TradeState,Status,RetailAmount,Freight,DiscountAmount,AdjustAmount,ActualAmount,RefundAmount,RefundQuantity"
	// var eagerLoad string = "order:orderItem,total"
	eagerLoad := "order:orderItem"
	var filters []string
	filters = append(filters, "UserId,equalTo:"+strconv.FormatInt(int64(userId), 10))
	if req.TradeState != nil {
		filters = append(filters, "TradeState,equalTo:"+strconv.FormatInt(int64(*req.TradeState), 10))
	} else {
		switch *req.Type {
		case 1: // 待付款
			filters = append(filters, "TradeState,equalTo:"+strconv.FormatInt(int64(globalkey.OrderTradeStateNotPay), 10))
		case 2: // 已付款、待发货
			filters = append(filters, "TradeState,equalTo:"+strconv.FormatInt(int64(globalkey.OrderTradeStatePaid), 10))
		case 3: // 已发货、待收货
			filters = append(filters, "TradeState,equalTo:"+strconv.FormatInt(int64(globalkey.OrderTradeStateShipped), 10))
		case 4: // 已完成
			stati := []string{
				strconv.FormatInt(int64(globalkey.OrderTradeStateConfirmed), 10),
				strconv.FormatInt(int64(globalkey.OrderTradeStateAutoConfirmed), 10),
				strconv.FormatInt(int64(globalkey.OrderTradeStateFulfilled), 10),
			}
			filters = append(filters, "TradeState,in:"+strings.Join(stati, ","))
		case 5: // 售后、退款
			filters = append(filters, "TradeState,moreThan:"+strconv.FormatInt(int64(globalkey.OrderTradeStateClosed), 10))
		default:
			filters = append(filters, "TradeState,moreThan:"+strconv.FormatInt(int64(globalkey.OrderTradeStateAdminDeleted), 10))
		}
	}

	var sorter *string
	if req.Sorter != nil {
		sorter = pointy.GetPointer(strings.TrimSpace(*req.Sorter))
	}
	var platformId uint32 = globalkey.ThirdPartyPlatformWechatMini

	res, err := l.svcCtx.OrderRpc.GetOrderList(l.ctx, &orderclient.BaseListReq{
		Offset:     uint32((page - 1) * pageSize),
		Limit:      uint32(pageSize),
		Preload:    pointy.GetPointer(preload),
		EagerLoad:  pointy.GetPointer(eagerLoad),
		Filter:     pointy.GetPointer(strings.Join(filters, ";")),
		Sorter:     sorter,
		Search:     req.Sn,
		VisitorId:  pointy.GetPointer(userId),
		PlatformId: pointy.GetPointer(platformId),
	})
	if err != nil {
		return nil, err
	}

	var hasNextPage bool
	var hasPreviousPage bool
	if res.HasNextPage != nil && *res.HasNextPage > 0 {
		hasNextPage = true
	}
	if res.HasPreviousPage != nil && *res.HasPreviousPage > 0 {
		hasPreviousPage = true
	}
	resp := &types.OrderListResp{
		BaseListInfo: types.BaseListInfo{
			// Total:           res.Total,
			HasNextPage:     hasNextPage,
			HasPreviousPage: hasPreviousPage,
		},
	}

	if len(res.List) > 0 {
		for _, v := range res.List {
			option := util.GetOptionByStatus(v.TradeState)
			// orderTypeText := util.GetOrderTypeText(v.OrderType)
			orderTradeStateText := util.GetTradeStateText(v.TradeState)
			// var createdAt *string
			// if v.UpdatedAt != nil {
			// 	createdAt = pointy.GetPointer(util.GetTimeFromNow(*v.UpdatedAt))
			// }
			var skus []*types.OrderSkuInfo
			if len(v.Skus) > 0 {
				for _, sku := range v.Skus {
					productTypeText := util.GetProductTypeText(sku.ProductType)
					skus = append(skus, &types.OrderSkuInfo{
						Id:             sku.Id,
						OrderId:        sku.OrderId,
						ProductCode:    sku.ProductCode,
						SkuId:          sku.SkuId,
						SkuCode:        sku.SkuCode,
						Sku:            sku.Sku,
						ImageId:        sku.ImageId,
						ImageUrl:       sku.ImageUrl,
						ProductId:      sku.ProductId,
						EntryId:        sku.EntryId,
						Title:          sku.Title,
						Slug:           sku.Slug,
						ProductType:    sku.ProductType,
						TypeText:       productTypeText,
						BrandId:        sku.BrandId,
						BrandTitle:     sku.BrandTitle,
						BrandSlug:      sku.BrandSlug,
						GemPrice:       sku.GemPrice,
						RetailPrice:    sku.RetailPrice,
						Quantity:       sku.Quantity,
						Weight:         sku.Weight,
						TradeState:     sku.TradeState,
						Status:         sku.Status,
						RefundAmount:   sku.RefundAmount,
						RefundQuantity: sku.RefundQuantity,
					})
				}
			}

			resp.List = append(resp.List, &types.TradeInfo{
				Id:       v.Id,
				ParentId: v.ParentId,
				UserId:   v.UserId,
				UserRank: v.UserRank,
				Buyer:    v.Buyer,
				Sn:       v.Sn,
				// OrderType:       v.OrderType,
				// OrderTypeText:   orderTypeText,
				Total:           v.Number,
				GemAmount:       v.GemAmount,
				RetailAmount:    v.RetailAmount,
				Freight:         v.Freight,
				DiscountAmount:  v.DiscountAmount,
				AdjustAmount:    v.AdjustAmount,
				ActualAmount:    v.ActualAmount,
				BalanceAmount:   v.BalanceAmount,
				RefundAmount:    v.RefundAmount,
				Gems:            v.Gems,
				TradeState:      v.TradeState,
				TradeStateText:  orderTradeStateText,
				Remark:          v.Remark,
				CreatedAt:       v.CreatedAt,
				UpdatedAt:       v.UpdatedAt,
				PaidAt:          v.PaidAt,
				ShippedAt:       v.ShippedAt,
				DeliveredAt:     v.DeliveredAt,
				ConfirmedAt:     v.ConfirmedAt,
				ReviewedAt:      v.ReviewedAt,
				FulfilledAt:     v.FulfilledAt,
				ClosedAt:        v.ClosedAt,
				AutoComfirmDays: v.AutoComfirmDays,
				Growth:          v.Growth,
				Integrals:       v.Integrals,
				Skus:            skus,

				CanCancel:  option.CanCancel,
				CanPay:     option.CanPay,
				CanRefund:  option.CanRefund,
				CanRemind:  option.CanRemind,
				CanTrack:   option.CanTrack,
				CanConfirm: option.CanConfirm,
				CanInvoice: option.CanInvoice,
				CanRemove:  option.CanRemove,
			})
		}
	}

	*headers = []*types.Header{
		{
			Key:   "x-class",
			Value: "com.djx.appview.OrderListPage",
		},
	}

	return resp, nil
}
